#include "Tool.h"
#include <unistd.h>
#include <fstream>
#include <sys/wait.h>

#define CHECK_PATH "/tmp/shellcheck_results.txt"

// 调用asciinema记录编辑器
/**
 * editor: 编辑器
 * shell_file: 文件名
 * recordFile: 记录文件名
 */
void use_asciinema(const std::string &editor,
                   const std::string &shell_file,
                   const std::string &recording_file)
{
    // 保存当前ncurses状态
    def_prog_mode();
    // 结束ncurses模式返回正常终端模式
    endwin();

    // 构建编辑器命令字符串
    std::string command = editor + " " + shell_file;

    // 创建子进程
    pid_t pid = fork();
    if (pid == -1)
    {
        // fork失败时恢复ncurses后再抛出异常
        initscr();
        reset_prog_mode();
        refresh();
        throw std::runtime_error("Failure to create a child process");
    }
    else if (pid == 0)
    {
        // 子进程 - 执行asciinema录制
        // 检查录制文件是否存在且非空
        std::ifstream file(recording_file);
        bool append = file.good() && file.peek() != std::ifstream::traits_type::eof();

        if (append)
        {
            execlp("asciinema",
                   "asciinema",
                   "rec",
                   "-q",        // 安静模式
                   "--stdin",   // 录制标准输入
                   "--append",  // 追加模式
                   "--command", // 指定要录制的命令
                   command.c_str(),
                   recording_file.c_str(),
                   nullptr);
        }
        else
        {
            execlp("asciinema",
                   "asciinema",
                   "rec",
                   "-q",
                   "--stdin",
                   "--command",
                   command.c_str(),
                   recording_file.c_str(),
                   nullptr);
        }

        // 如果execlp返回则说明执行失败
        _exit(EXIT_FAILURE);
    }
    else
    {
        // 父进程 - 等待子进程完成
        int status;
        waitpid(pid, &status, 0);

        // 无论成功失败都恢复ncurses状态
        reset_prog_mode();
        refresh();

        if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
        {
            throw std::runtime_error("asciinema recording failure");
        }
    }
}

//调用shellcheck
/**
 * 传入一个shell脚本文件
 */
void use_shellcheck(const std::string &shell_file)
{
    pid_t pid = fork();

    if (pid == 0)
    { // 子进程
        // 构建ShellCheck命令
        std::string command = "shellcheck " + shell_file + " > " + CHECK_PATH + " 2>&1";

        // 使用execl执行命令
        execl("/bin/sh", "sh", "-c", command.c_str(), (char *)NULL);

        // 如果execl失败
        _exit(EXIT_FAILURE);
    }
    else if (pid > 0)
    { // 父进程
        waitpid(pid, NULL, 0);
    }
    else
    {
        throw std::runtime_error("Failure to create a child process");
    }
}
